<template>
    <div class="jvc-layout" :class="{ 'acti': btnIds.btnIntial }">
        <div class="msg">{{ showStatus() }} {{ agentStateTimeCount }}</div>

        <div class="btb-box" v-if="btnIds.btnIntial && !btnIds.btn9">
            <img class="btn-img" src="../../assets/images/answer.png" @click="Answer()" alt="接通" srcset="">
            <div class="btn-text">接通</div>
        </div>
        <div class="btb-box disabled" v-else>
            <img class="btn-img" src="../../assets/images/answer_1.png" alt="接通" srcset="">
            <div class="btn-text">接通</div>
        </div>
        <div class="line"></div>
        <div class="btb-box" v-if="btnIds.btnIntial && !btnIds.btn6">
            <img class="btn-img" src="../../assets/images/cacel.png" @click="Disconnect()" alt="挂断" srcset="">
            <div class="btn-text">挂断</div>
        </div>
        <div class="btb-box disabled" v-else>
            <img class="btn-img" src="../../assets/images/cacel_1.png" alt="挂断" srcset="">
            <div class="btn-text">挂断</div>
        </div>

    </div>
</template>

<script>
import CinVccBar from '../../api/vccbarExtension'
import { EventBus } from "@/utils/event-bus";
function showLog(Text) {
    console.log(Text);
}
export default {
    name: 'JVC',
    data() {
        return {
            cinVccBar: null,
            mainServer: 'vcs.cuopen.net',
            mainPort: 18080,
            // 定义按钮绑定参数，进行按钮绑定
            btnIds: {
                btnIntial: false,
                btn0: false,
                btn1: false,
                btn2: false,
                btn3: false,
                btn4: false,
                btn5: false,
                btn6: false,
                btn7: false,
                btn8: false,
                btn9: false,
                btn10: false,
                btn11: false,
                btn12: false,
                btn13: false,
                btn14: false,
                btn15: false,
                btn16: false,
                btn17: false,
                btn18: false,
                btn19: false,
                btn20: false,
                btn21: false,
                btn22: false,
                btn23: false,
                btn24: false,
                btn25: false,
                btn26: false,
                btn27: false,
                btn28: false,
                btn29: false,
                btn30: false,
                btn31: false
            },
            formSign: {
                ctiServer: 'vcs.cuopen.net',
                ctiPort: 18080,
                monitorServer: 'vcs.cuopen.net',
                monitorPort: 18080,
                sipServer: 'vcs.cuopen.net',
                sipPort: 18080,
                sipxPath: 'sbc',
                barType: 3,
                shortId: '000001',
                agentPwdType: 0,
                agentPwd: 'd8fc814326d84afee6cd9c44e00ac412',
                extensionPwdType: 1,
                sipPwd: 'CSiGbSvm7r7FbZjcF1+CBw==',
                vccId: '100075',
                agentId: '0000108886661002',
                dn: '0000028886661002',
                appType: 0,
                defaultBtn: '0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,19,20,21,22,23,24,27,30,31',
                hiddenBtn: '7,8,10,11,12,13',
                logMsgType: 16,
                logSipType: 1,
            },
            agentStatusText: '',
            agentStateTimeCount: '',
            agentState: 0,
            ringflag: 0,
            agentStateTime: 0,
            cinccTimer: null
        }
    },
    created() {
        EventBus.$on('PageMakeCall', (destNum) => {

            this.MakeCall(destNum)
        })
    },
    mounted() {
        this._initVccBar()
    },
    destroyed() {
        this.cinVccBar.removeAllListeners()
        this.cinVccBar.exit()
    },
    methods: {
        timeToTimeTxt(time) {
            let hourTime = 0
            let minuteTime = 0
            let secondTime = parseInt(time)
            if (secondTime > 60) {
                // 获取分钟，除以60取整数，得到整数分钟
                minuteTime = parseInt(secondTime / 60)
                // 获取秒数，秒数取佘，得到整数秒数
                secondTime = parseInt(secondTime % 60)
                // 如果分钟大于60，将分钟转换成小时
                if (minuteTime > 60) {
                    // 获取小时，获取分钟除以60，得到整数小时
                    hourTime = parseInt(minuteTime / 60)
                    // 获取小时后取佘的分，获取分钟除以60取佘的分
                    minuteTime = parseInt(minuteTime % 60)
                }
            }
            if (hourTime < 10) {
                hourTime = '0' + hourTime
            }
            if (minuteTime < 10) {
                minuteTime = '0' + minuteTime
            }
            if (secondTime < 10) {
                secondTime = '0' + secondTime
            }
            return hourTime + ':' + minuteTime + ':' + secondTime
        },
        setAllBtnDisable() {
            for (let i = 0; i < 32; i++) {
                this.setBtnStatus('btn' + i, true)
            }
        },
        /**
            * 
            * @param btnIDS 
            *  0 座席状态 没有方法对应，只是展示状态 常用
               1 示忙 SetBusy 常用
               2 示闲 SetIdle 常用
               3 呼出 MakeCall/CallIn 常用
               4 保持 Hold 常用
               5 接回 RetrieveHold 常用
               6 挂断 Disconnect 常用
               7 转移 Transfer 常用
               8 会议 Conference 常用
               9 应答 Answer 常用
               10 转出 TransferOut 常用
               11 咨询 Consult 常用
               12 二次拨号 SendDTMF 常用
               13 桥接 Bridge 常用
               14 切换 Alternate 弃用
               15 设置 Configurate 常用
               16 强制复位 FroceReset 常用
               修改历史
               3/14/2025 正文 第 35 页
               编号 名称 说明(对应方法) 标注
               17 录音 BeginRecord 不常用
               18 停止录音 StopRecord 不常用
               19 监听 Listen 常用
               20 强插 Insert 常用
               21 拦截、代答 Intercept 常用
               22 强拆 ForeReleaseCall 常用
               23 放音 BeginPlay 不常用
               24 结束放音 StopPlay 不常用
               25 加锁 Lock 不常用
               26 解锁 UnLock 不常用
               27 静音 Mute 常用
               28 返回 Callback 不常用
               29 重拨 ReCall 不常用
               30 辅助 Help 常用
               31 连接 Connect 常用
            */

        updateBtns(btnIDs) {
            if (btnIDs.indexOf('|') > -1) {
                const arrIDS = btnIDs.split('|')
                this.setAllBtnDisable()
                for (let i = 0; i < arrIDS.length; i++) {
                    this.setBtnStatus('btn' + parseInt(arrIDS[i]), false)
                }
                EventBus.$emit('callBtn',this.btnIds.btn3)
                if (this.btnIds.btn3) {
                    localStorage.setItem('callBtn',1)
                }else{
                    localStorage.setItem('callBtn',2)
                }
                
            }
        },
        setBtnStatus(id, flag) {
            this.btnIds[id] = flag;
        },
        showStatus() {
            if (this.agentStatusText != "")
                return this.agentStatusText;
            switch (parseInt(this.agentState)) {
                case 0:
                    return '签出'
                case 1:
                    return '忙碌'
                case 2:
                    return '空闲'
                case 3:
                    if (this.ringflag == 1) {
                        return '振铃中'
                    } else {
                        return '通话中'
                    }
                case 4:
                    return '后处理'
            }
        },
        _initVccBar() {
            //    初始化创建电话条对象
            debugger
            this.formSign.ctiServer = this.mainServer;
            this.formSign.monitorServer = this.mainServer;
            this.formSign.sipServer = this.mainServer;
            this.formSign.sipPort = this.mainPort;
            if (this.formSign.barType == 1) {
                this.formSign.ctiPort = 14800;
                this.formSign.monitorPort = 4502;
            }
            else {
                this.formSign.monitorPort = this.mainPort;
                this.formSign.ctiPort = this.mainPort;
            }
            this.formSign.agentId = "000010" + this.formSign.vccId + this.formSign.shortId;
            this.formSign.dn = "000002" + this.formSign.vccId + this.formSign.shortId;

            CinVccBar.load(this.formSign.barType).then(ve => {
                ve.removeAllListeners()
                //      这里的ve是电话条对象
                this.cinVccBar = ve
                //      设置监听事件
                this.cinVccBar.on('reportBtnStatus', this.OnReportBtnStatus)
                this.cinVccBar.on('prompt', this.OnPrompt)
                this.cinVccBar.on('agentWorkReport', this.OnAgentWorkReport)
                this.cinVccBar.on('eventPrompt', this.OnEventPrompt)
                this.cinVccBar.on('methodResponseEvent', this.OnMethodResponseEvent)
                this.cinVccBar.on('callRing', this.OnCallRing)
                this.cinVccBar.on('answerCall', this.AnswerCall)
                this.cinVccBar.on('callEnd', this.OnCallEnd)
                this.cinVccBar.on('initalSuccess', this.OnInitalSuccess)
                this.cinVccBar.on('initalFailure', this.OnInitalFailure)
                this.cinVccBar.on('barExit', this.OnBarExit)
                this.cinVccBar.on('updateVideoWindow', this.OnUpdateVideoWindow)
                this.cinVccBar.on('updateMediaEvent', this.OnUpdateMediaEvent)
                this.cinVccBar.on('agentStatusTimeChange', this.OnAgentStatusTimeChange)
                //      设置参数属性
                this.cinVccBar.setBarAttributes(this.formSign)
                //      电话条登录
                this.cinVccBar.Initial()
            })
        },
        // 坐席状态
        OnReportBtnStatus(btnIDS) {
            showLog('【ReportBtnStatus】：\r\n')
            this.agentState = this.cinVccBar.GetAgentStatus()
            showLog('         可现状态值   ：【' + btnIDS + '】\r\n 当前座席状态：【' + this.agentState + '】\r\n')
            showLog(' *******************************************************************\r\n')
            // 根据这个命令可以控制各个按钮对应的方法和可用状态
            this.updateBtns(btnIDS)
        },

        // 电话条事件
        OnPrompt(code, description) {
            showLog('【OnPrompt】：\r\n')
            showLog(' code:【' + code + '】 description:【' + description + '】\r\n')
            showLog(' *******************************************************************\r\n')
        },

        /**
         * 工作信息报告
         * @param workStatus 座席状态 
         *                 -1 没有初始化
                            0 登录CTI成功
                            2 座席就绪
                            3 座席忙碌
                            4 座席外拨
                            5 座席振铃
                            7 座席挂机处于空闲状态
                            8 座席挂机处于后处理状态
                           10 座席接通呼入电话
                           11 座席接通呼出电话
                           12 座席正在咨询中
                           13 座席在会议中
                           14 用户处于保持中
                           16 座席正在监听中
                           17 座席正在辅助中!
                           18 座席正在强插中
                           20 座席外呼,对方正在振铃
                           21 座席咨询,对方正在振铃
                           22 桥接中，座席处于保持状态
                           23 座席外呼中!
                           24 座席内呼中!
                           25 咨询失败，用户保持状态
                           26 外呼后座席振铃前状态
                           27 内部后座席振铃前状态
                           28 多方会议中
         * @param description 提示信息
         */
        OnAgentWorkReport(workStatus, description) {
            // console.log(this)
            if (this) {
                this.agentStateTime = 0
            }
            showLog('【OnAgentWorkReport】 场景编号：【' + workStatus + '】 场景描述：【' + description + '】\r\n')
            showLog(' *******************************************************************\r\n')
        },
        /**
         * 电话条底层事件报告
         * @param code 示号码
         * @param description 提示信息
         */
        OnEventPrompt(code, description) {
            showLog('【OnEventPrompt】：\r\n')
            showLog(' code:【' + code + '】 description:【' + description + '】\r\n')
            showLog(' *******************************************************************\r\n')
        },
        /**
         * 
         * @param cmdName 
         * @param param 
         */
        OnMethodResponseEvent(cmdName, param) {
            showLog('【OnMethodResponseEvent】 cmdName：【' + cmdName + '】 param：【' + param + '】\r\n')
            showLog(' *******************************************************************\r\n')
        },
        /**
         * 来电振铃
         * @param callingNo 主叫号码
         * @param calledNo 被叫号码
         * @param orgCalledNo 原始被叫号码
         * @param callData 呼叫数据(客户拨 IVR 时的按键)
         * @param serialID 呼叫座席标识
         * @param serviceDirect 呼叫类型/方向
         * @param callID 呼叫标示
         * @param userParam 用户参数
         * @param taskID 任务ID
         * @param userDn 用户DN
         * @param agentDn 座席DN
         * @param areaCode 区号
         * @param fileName 文件名
         * @param networkInfo 网络信息
         * @param queueTime 队列时间
         * @param opAgentID 操作座席ID
         * @param ringTimer 振铃时间
         * @param projectID 项目ID
         * @param callingNo 
         * @param calledNo 
         * @param orgCalledNo 
         * @param callData 
         * @param serialID 
         * @param serviceDirect 
         * @param callID 
         * @param userParam 
         * @param taskID 
         * @param userDn 
         * @param agentDn 
         * @param areaCode 
         * @param fileName 
         * @param networkInfo 
         * @param queueTime 
         * @param opAgentID 
         * @param ringTimer 
         * @param projectID 
         * @param serverName 
         * @param AccessCode 
         * @param TaskName 
         * @param CityName 
         * @param UserType 
         * @param LastServiceId 
         * @param LastServiceName 
         */
        OnCallRing(callingNo, calledNo, orgCalledNo, callData, serialID, serviceDirect, callID, userParam, taskID, userDn, agentDn, areaCode, fileName, networkInfo, queueTime, opAgentID, ringTimer, projectID, serverName, AccessCode, TaskName, CityName, UserType, LastServiceId, LastServiceName) {
            showLog('【OnCallRing】：\r\n')
            showLog('         callingNo：【' + callingNo + '】\r\n')
            showLog('         calledNo：【' + calledNo + '】\r\n')
            showLog('         orgCalledNo：【' + orgCalledNo + '】\r\n')
            showLog('         callData：【' + callData + '】\r\n')
            showLog('         callID ：【' + callID + '】\r\n')
            showLog('         serialID ：【' + serialID + '】\r\n')
            showLog('         serviceDirect ：【' + serviceDirect + '】\r\n')
            showLog('         userParam ：【' + userParam + '】\r\n')
            showLog('         taskID ：【' + taskID + '】\r\n')
            showLog('         userDn ：【' + userDn + '】\r\n')
            showLog('         agentDn ：【' + agentDn + '】\r\n')
            showLog('         areaCode ：【' + areaCode + '】\r\n')
            showLog('         fileName ：【' + fileName + '】\r\n')
            showLog('         networkInfo：【' + networkInfo + '】\r\n')
            showLog('         queueTime ：【' + queueTime + '】\r\n')
            showLog('         opAgenID ：【' + opAgentID + '】\r\n')
            showLog('         ringTimer ：【' + ringTimer + '】\r\n')
            showLog('         projectID ：【' + projectID + '】\r\n')
            showLog("         serverName ：【" + serverName + "】\r\n")
            showLog("         AccessCode ：【" + AccessCode + "】\r\n")
            showLog("         TaskName ：【" + TaskName + "】\r\n")
            showLog("         CityName ：【" + CityName + "】\r\n")
            showLog("         UserType ：【" + UserType + "】\r\n")
            showLog("         LastServiceId ：【" + LastServiceId + "】\r\n")
            showLog("         LastServiceName ：【" + LastServiceName + "】\r\n")
            showLog(' *******************************************************************\r\n')
            this.ringflag = 1;
        },
        /**
         * 座席接通事件
         * @param userNo 用户号码
         * @param answerTime 接通时间
         * @param serialID 呼叫座席标识
         * @param serviceDirect 呼叫类型/方向
         * @param callID 呼叫标示
         * @param userParam 透明参数
         * @param taskID 呼任务号或者人工服务号
         * @param AV 外线音视频: 空或者 audio:音频; video:视频
         * @param TC 外线终端能力: video:表示支持视频 空或者 audio:表示只支持音频
        /** */
        AnswerCall(userNo, answerTime, serialID, serviceDirect, callID, userParam, taskID, AV, TC) {
            showLog(' 【OnAnswerCall】:\r\n')
            showLog('        answerTime ：【' + answerTime + '】\r\n')
            showLog('        userNo ：【' + userNo + '】\r\n')
            showLog('        callID ：【' + callID + '】\r\n')
            showLog('        serialID ：【' + serialID + '】\r\n')
            showLog('        serviceDirect ：【' + serviceDirect + '】\r\n')
            showLog('        userParam ：【' + userParam + '】\r\n')
            showLog('        taskID ：【' + taskID + '】\r\n')
            showLog('        AV ：【' + AV + '】\r\n')
            showLog('        TC ：【' + TC + '】\r\n')
            showLog(' *******************************************************************\r\n')
            this.ringflag = 0;

        },
        /**
         * 电话结束事件
         * @param callID 
         * @param serialID 
         * @param serviceDirect 
         * @param userNo 
         * @param bgnTime 
         * @param endTime 
         * @param agentAlertTime 
         * @param userAlertTime 
         * @param fileName 
         * @param directory 
         * @param disconnectType 
         * @param userParam 
         * @param taskID 
         * @param serverName 
         * @param networkInfo 
         */
        OnCallEnd(callID, serialID, serviceDirect, userNo, bgnTime, endTime, agentAlertTime, userAlertTime, fileName, directory, disconnectType, userParam, taskID, serverName, networkInfo) {
            showLog(' 【OnCallEnd】:\r\n')
            showLog('         fileName   ：【' + fileName + '】\r\n')
            showLog('         directory：【' + directory + '】\r\n')
            showLog('         bgnTime  ：【' + bgnTime + '】\r\n')
            showLog('         endTime  ：【' + endTime + '】\r\n')
            showLog('         userNo ：【' + userNo + '】\r\n')
            showLog('         CallID   ：【' + callID + '】\r\n')
            showLog('         SerialID ：【' + serialID + '】\r\n')
            showLog('         ServiceDirect  ：【' + serviceDirect + '】\r\n')
            showLog('         userAlertTime  ：【' + userAlertTime + '】\r\n')
            showLog('         agentAlertTime ：【' + agentAlertTime + '】\r\n')
            showLog('         fileName      ：【' + fileName + '】\r\n')
            showLog('         directory      ：【' + directory + '】\r\n')
            showLog('         disconnectType      ：【' + disconnectType + '】\r\n')
            showLog('         userParam      ：【' + userParam + '】\r\n')
            showLog('         taskID         ：【' + taskID + '】\r\n')
            showLog('         serverName         ：【' + serverName + '】\r\n')
            showLog('         networkInfo         ：【' + networkInfo + '】\r\n')
            showLog(' *******************************************************************\r\n')
            this.ringflag = 0;

        },
        /**
         * 电话条初始化成功事件报
         */
        OnInitalSuccess() {
            showLog('#############OnInitalSuccess################\r\n')
            showLog('当前版本：' + this.cinVccBar.GetVersion() + "\r\n")
            console.info('OnBarInitalSuccess')
            // this.cinVccBar.Configurate({"sip":{"width":480,"height":640,"framerate":15,"bandwidth":1000,"fit":"fill"}});
            this.btnIds.btnIntial = true;
            if (!this.cinccTimer) {
                const me = this
                me.cinccTimer = setInterval(function () {
                    me.agentStateTime++
                }, 1000)
            }
        },
        /**
         * 电话条初始化失败事件报告
         * @param code 错误码
         * 0 电话类型参数错误
         * 1 软电话注册失败+具体原因
         * 2 没有检测到座席卡
         * 3 软电话注册失败+具体原因
         * 4 CTI 服务器注册失败+具体原因
         * 5 监控服务器注册失败+具体原因        
         * @param description 错误描述
         */
        OnInitalFailure(code, description) {
            this.btnIds.btnIntial = false;
            this.cinVccBar = null;
            showLog('【OnInitalFailure】\r\n 【' + code + '】 【' + description + '】\r\n')
            showLog(' *******************************************************************\r\n')
        },
        /**
         * 电话条退出事件报告
         * @param code 
         * @param description 
         */
        OnBarExit(code, description) {
            this.btnIds.btnIntial = false;
            this.cinVccBar = null;
            showLog('【OnBarExit】 \r\n【' + code + '】 【' + description + '】\r\n')
            showLog(' *******************************************************************\r\n')
        },
        /**
         * 视频呼叫的回调
         * @param param 
         */
        OnUpdateVideoWindow(param) {

        },
        /**
         * 通话中媒体发生变化信息报告
         * @param cause 原因值，200 成功，400 失败，0 外线自己更新媒体信息
         * @param number 外线号码
         * @param av 媒体类型：”audio” 音频，” video”视频
         */
        OnUpdateMediaEvent(cause, number, av) {
            showLog("【OnUpdateMediaEvent】 \r\n cause:【" + cause + "】 ");
            showLog(" number:【" + number + "】  ");
            showLog(" av:【" + av + "】  ");
            showLog(" *******************************************************************\r\n");

        },
        OnAgentStatusTimeChange(e) {
            this.agentStatusText = e.agentStatusText;
            this.agentStateTimeCount = e.timerCount;
        },
        // 拨打电话
        MakeCall(destNum) {
            this.cinVccBar.MakeCall({
                destNum: destNum,
                av: 1,
                callback: (res) => {
                    console.log(res);

                }
            })
            this.ringflag = 1;
        },
        // 挂断电话
        Disconnect() {
            this.cinVccBar.Disconnect({
                callType: 1,
                callback: (data) => {

                }
            });
        },
        // 接听电话
        Answer() {
            this.cinVccBar.Answer({
                recordFlag: 0,
                callback: (data)=> { 
                    
                }
            });
        },
        beforeDestroy() {
            if (this.cinccTimer) {
                clearInterval(this.cinccTimer)
                this.cinccTimer = null
            }
            EventBus.$off('PageMakeCall', {})
        }

    }

}
</script>

<style scoped>
.jvc-layout {
    position: fixed;
    top: 50vh;
    left: 20px;
    height: max-content;
    background-color: rgba(255, 255, 255, 0.6);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    border: solid 1px #f1f1f1;
    box-shadow: 18px 21px 26px -5px rgba(0, 0, 0, 0.1);
    z-index: 9999;
}

.acti {
    background-color: rgba(218, 92, 113, 0.6);
}

.btb-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    cursor: pointer;
    padding: 20px;
    border-radius: 10px;
    box-sizing: border-box;
}

.btb-box:hover {
    background: rgba(4, 56, 134, 0.8);
    ;
}

.btn-img {
    width: 40px;
    height: 40px;
    margin-bottom: 10px;
}

.disabled {
    color: #cdcdcd;
}

.line {
    width: 100%;
    height: 1px;
    background-color: #f1f1f1;
}

.msg {
    color: #fff;
    font-size: 14px;
    padding: 10px 20px;
}
</style>